package com.codeplay.security.service;

import com.codeplay.domain.entity.AdminUser;
import com.codeplay.domain.entity.CreatorUser;
import com.codeplay.domain.entity.ChildUser;
import com.codeplay.domain.entity.ParentUser;
import com.codeplay.domain.repository.AdminUserRepository;
import com.codeplay.domain.repository.CreatorUserRepository;
import com.codeplay.domain.repository.ChildUserRepository;
import com.codeplay.domain.repository.ParentUserRepository;
import com.codeplay.security.dto.AuthRequest;
import com.codeplay.security.dto.AuthResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Collections;

@Service
@RequiredArgsConstructor
public class AuthService implements UserDetailsService {
    private final AdminUserRepository adminUserRepository;
    private final CreatorUserRepository creatorUserRepository;
    private final ChildUserRepository childUserRepository;
    private final ParentUserRepository parentUserRepository;
    private final PasswordEncoder passwordEncoder;
    private final JwtService jwtService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 按顺序查找不同类型的用户
        AdminUser adminUser = adminUserRepository.findByUsername(username).orElse(null);
        if (adminUser != null) {
            return new User(adminUser.getUsername(), adminUser.getPassword(),
                    Collections.singletonList(new SimpleGrantedAuthority("ROLE_ADMIN")));
        }

        CreatorUser creatorUser = creatorUserRepository.findByUsername(username).orElse(null);
        if (creatorUser != null) {
            return new User(creatorUser.getUsername(), creatorUser.getPassword(),
                    Collections.singletonList(new SimpleGrantedAuthority("ROLE_CREATOR")));
        }

        ChildUser childUser = childUserRepository.findByUsername(username).orElse(null);
        if (childUser != null) {
            return new User(childUser.getUsername(), childUser.getPassword(),
                    Collections.singletonList(new SimpleGrantedAuthority("ROLE_CHILD")));
        }

        ParentUser parentUser = parentUserRepository.findByUsername(username).orElse(null);
        if (parentUser != null) {
            return new User(parentUser.getUsername(), parentUser.getPassword(),
                    Collections.singletonList(new SimpleGrantedAuthority("ROLE_PARENT")));
        }

        throw new UsernameNotFoundException("User not found with username: " + username);
    }

    public AuthResponse authenticate(AuthRequest request) {
        UserDetails userDetails = loadUserByUsername(request.getUsername());
        
        if (!passwordEncoder.matches(request.getPassword(), userDetails.getPassword())) {
            throw new UsernameNotFoundException("Invalid password");
        }

        String token = jwtService.generateToken(userDetails);
        String refreshToken = jwtService.generateRefreshToken(userDetails);

        return new AuthResponse(
                token,
                refreshToken,
                userDetails.getAuthorities().iterator().next().getAuthority(),
                userDetails.getUsername()
        );
    }

    public AuthResponse refreshToken(AuthRequest request) {
        UserDetails userDetails = loadUserByUsername(request.getUsername());
        String token = jwtService.generateToken(userDetails);
        String refreshToken = jwtService.generateRefreshToken(userDetails);

        return new AuthResponse(
                token,
                refreshToken,
                userDetails.getAuthorities().iterator().next().getAuthority(),
                userDetails.getUsername()
        );
    }
} 